package edu.ntu.cloudroid.client;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TimeZone;

import edu.ntu.cloudroid.model.friend.FriendInfo;
import edu.ntu.cloudroid.nongui.com.AbstractResponse;
import edu.ntu.cloudroid.nongui.com.Communicator;
import edu.ntu.cloudroid.nongui.com.LocationRequestWithInputs;
import edu.ntu.cloudroid.nongui.com.VitalDataRequestWithInputs;

class LocationRequestGenerator {
	public static final String DEFAULT_DATE = "2011-01-01 00:00";
	private List<LocationRequestWithInputs> locationRequests;
	private int i;
	public LocationRequestGenerator(int nRequests, int nusers, long seed, String filename) throws Exception {
		i = 0;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
		Date startingDate = sdf.parse(DEFAULT_DATE);
		// generate the 
		Generator.generateLocationDataFromFile(filename, nusers, startingDate, 10, 10);
	}
	
	public synchronized LocationRequestWithInputs getNext() {
		if (i < locationRequests.size()) {
			return locationRequests.get(i++);
		} else
			return null;
	}
}

class CapacityFinderThread extends Thread {
	private Communicator communicator;
	private int nRequest;
	private int operationType;
	private Random rand;
	private LocationRequestGenerator requestGenerator;

	public CapacityFinderThread(Random rand, String host, int port, int nRequest, int operationType, LocationRequestGenerator requestGenerator) {
		communicator = new Communicator(null, host, port);
		this.requestGenerator = requestGenerator;

		this.nRequest = nRequest;
		this.operationType = operationType;
		this.rand = rand;
	}
	
	public CapacityFinderThread(Random rand, String url,  int nRequest, int operationType, LocationRequestGenerator requestGenerator) {
		communicator = new Communicator(url);
		this.requestGenerator = requestGenerator;

		this.nRequest = nRequest;
		this.operationType = operationType;
		this.rand = rand;
	}

	@Override
	public void run() {
		String user1, user2;
		FriendInfo fi;
		Set<LocationObject> locs = Generator.locFromFile;
		for (int i = 0; i < nRequest; i++) {
			fi = Generator.friendList.get(this.rand.nextInt(Generator.friendList.size()));
			if (fi==null){
				System.out.println(i);
				continue;
			}
			//if (i%2==0){
			//user1 = "user_"+rand.nextInt(1000)+"@gmail.com";
			//user2 = "user_"+rand.nextInt(1000)+"@gmail.com";
			//}
			//else{
				user1 = fi.getUser1();
				user2 = fi.getUser2();
			//}
			if (0 == operationType) {
				/*System.out.println(communicator.getData(
						new VitalDataRequestWithInputs("user_"
								+ rand.nextInt(700) + "@gmail.com", 80, 90))
						.getAccessDecision());*/
				System.out.println("requesting "+user1+", "+user2);
				AbstractResponse ar = communicator.getData(
					new VitalDataRequestWithInputs(user1, user2, 80, 90));
				
			} else if (1 == operationType) {
				LocationObject lo = (LocationObject) locs.toArray()[this.rand
						.nextInt(locs.size())];
				if (null == lo)
					break;

				System.out.println("requesting "+fi.getUser1()+", "+fi.getUser2()+" at "+lo.longt+" - "+lo.lat);
				LocationRequestWithInputs request = new LocationRequestWithInputs(
						fi.getUser1(), fi.getUser2(), lo.longt, lo.lat);
				AbstractResponse ar = communicator.getData(request);
				String s = (String)ar.getReturnedData().keySet().toArray()[0];
				String s1 = (String) ar.getReturnedData().get(s).keySet().toArray()[0];
				System.out.println("data size = "+ar.getReturnedData().get(s).get(s1).size());
			}
		}
	}
}

public class CapacityFinder {
	public static int NREQUEST = 250;
	
	public static void main(String[] args) throws Exception {
		int i=0;
		String url="";
		String targetAddress="";
		int targetPort=0;
		if (args.length==4){
			url = args[0];
			i=1;
		}
		else{
			targetAddress = args[0];
			targetPort = Integer.parseInt(args[1]);
			i=2;
		}
		int operationType = Integer.parseInt(args[i]);
		int nparallel = Integer.parseInt(args[i+1]);
		long seed = Long.parseLong(args[i+2]);
		Random rand = new Random(seed);

			Generator.generateFriendsFromFile("dataset/location/friends1000");
		if (operationType==1){
						SimpleDateFormat sdf = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm");
					sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
					Date startingDate = sdf
							.parse(LocationRequestGenerator.DEFAULT_DATE);
					// generate the
					Generator.generateLocationDataFromFile(
							"dataset/location/checkin_10_per_person",
							1000, startingDate, 10, 10);
		}
		// init
		//CapacityFinderThread initiator = new CapacityFinderThread(rand, targetAddress, targetPort, 1, operationType);
		//initiator.start();
		//initiator.join();
		//initiator = null;

		//	System.out.println(operationType + "-" + nparallel + "@" + frequency);
	
		
		/*if (1 == operationType)
			requestGenerator = new LocationRequestGenerator(NREQUEST * nparallel, Integer.parseInt(args[6]), seed, args[5]);
	*/	// prepare
		CapacityFinderThread[] clients = new CapacityFinderThread[nparallel];
		for (i = 0; i < nparallel; i++) {
			if (url.equals(""))
				clients[i] = new CapacityFinderThread(new Random(seed+i), targetAddress,
						targetPort, NREQUEST, operationType, null);
			else
				clients[i] = new CapacityFinderThread(new Random(seed+i), url, NREQUEST, operationType, null);
		}

		// start
		for (CapacityFinderThread client : clients) {
			client.start();
		}

		// finalize
		for (CapacityFinderThread client : clients) {
			client.join();
		}
	}

}
